package artin.A3D7.serices
{
	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	
	public class DragController extends EventDispatcher
	{
		public var zoomSpeed:Number = 1.2;
		public var rotationSpeed:Number = 1;
		public var angleSpeed:Number = 1;
		public var distanceMin:Number = NaN;
		public var distanceMax:Number = NaN;
		public var rotationMin:Number = NaN;
		public var rotationMax:Number = NaN;
		public var angleMin:Number = NaN;
		public var angleMax:Number = NaN;
		private var distance:Number;
		private var rotation:Number;
		private var angle:Number;
		private var dragEnabled:Boolean = true;
		private var eventObj:InteractiveObject;
		private var saveRotation:Number;
		private var saveAngle:Number;
		private var saveMousePos:Point;
		private var dragPosition:Vector3D;
		public var onMoveCamera:Function;
		
		public function DragController(param1:InteractiveObject, param2:Number = 0, param3:Number = 30, param4:Number = 1000)
		{
			this.dragPosition = new Vector3D();
			this.distance = param4;
			this.angle = param3;
			this.rotation = param2;
			this.eventObj = param1;
			this.eventObj.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDownHandler);
			this.eventObj.stage.addEventListener(MouseEvent.MOUSE_WHEEL, this.onMsWheel);
			return;
		}// end function
		
		public function get position() : Vector3D
		{
			return this.dragPosition;
		}// end function
		
		public function get enabled() : Boolean
		{
			return this.dragEnabled;
		}// end function
		
		public function set enabled(param1:Boolean) : void
		{
			this.onMouseUpHandler(null);
			this.dragEnabled = param1;
			return;
		}// end function
		
		private function dispose() : void
		{
			this.eventObj.removeEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDownHandler);
			this.eventObj.stage.removeEventListener(MouseEvent.MOUSE_UP, this.onMouseUpHandler);
			this.eventObj.stage.removeEventListener(MouseEvent.MOUSE_WHEEL, this.onMsWheel);
			this.eventObj.stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.onMouseMoveHandler);
			return;
		}// end function
		
		private function onMsWheel(event:MouseEvent) : void
		{
			if (!this.dragEnabled)
			{
				return;
			}
			var _loc_2:* = event.delta < 0 ? (-1) : (1);
			this.distance = this.distance * Math.pow(this.zoomSpeed, -_loc_2);
			this.distance = this.checkLimit(this.distance, this.distanceMin, this.distanceMax);
			this.updatePosition();
			return;
		}// end function
		
		public function dispatch() : void
		{
			dispatchEvent(new Event(Event.CHANGE));
			if (this.onMoveCamera != null)
			{
				this.onMoveCamera.apply(null, [this.dragPosition]);
			}
			return;
		}// end function
		
		public function setDistanceLimit(param1:Number, param2:Number) : void
		{
			this.distanceMin = param1;
			this.distanceMax = param2;
			return;
		}// end function
		
		public function setAngleLimit(param1:Number, param2:Number) : void
		{
			this.angleMin = param1;
			this.angleMax = param2;
			return;
		}// end function
		
		public function setRotationLimit(param1:Number, param2:Number) : void
		{
			this.rotationMin = param1;
			this.rotationMax = param2;
			return;
		}// end function
		
		private function onMouseDownHandler(event:MouseEvent) : void
		{
			if (!this.dragEnabled)
			{
				return;
			}
			this.eventObj.stage.addEventListener(MouseEvent.MOUSE_MOVE, this.onMouseMoveHandler);
			this.eventObj.stage.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUpHandler);
			this.saveRotation = this.rotation;
			this.saveAngle = this.angle;
			this.saveMousePos = new Point(this.eventObj.mouseX, this.eventObj.mouseY);
			return;
		}// end function
		
		private function onMouseMoveHandler(event:MouseEvent) : void
		{
			if (!this.dragEnabled)
			{
				return;
			}
			var _loc_2:* = new Point(this.eventObj.mouseX, this.eventObj.mouseY).subtract(this.saveMousePos);
			this.rotation = this.saveRotation - _loc_2.x * this.rotationSpeed;
			this.rotation = this.checkLimit(this.rotation, this.rotationMin, this.rotationMax);
			this.angle = Math.max(-89, Math.min(89, this.saveAngle + _loc_2.y * this.angleSpeed));
			this.angle = this.checkLimit(this.angle, this.angleMin, this.angleMax);
			this.updatePosition();
			return;
		}// end function
		
		private function checkLimit(param1:Number, param2:Number, param3:Number) : Number
		{
			if (!isNaN(param2) && param1 < param2)
			{
				param1 = param2;
			}
			if (!isNaN(param3) && param1 > param3)
			{
				param1 = param3;
			}
			return param1;
		}// end function
		
		private function onMouseUpHandler(event:MouseEvent) : void
		{
			this.eventObj.stage.removeEventListener(MouseEvent.MOUSE_MOVE, this.onMouseMoveHandler);
			this.eventObj.stage.removeEventListener(MouseEvent.MOUSE_UP, this.onMouseUpHandler);
			this.updatePosition();
			return;
		}// end function
		
		private function updatePosition() : void
		{
			var _loc_1:* = Math.cos(Math.PI / 180 * this.angle);
			var _loc_2:* = Math.cos(Math.PI / 180 * this.rotation) * this.distance * _loc_1;
			var _loc_3:* = Math.sin(Math.PI / 180 * this.angle) * this.distance;
			var _loc_4:* = Math.sin(Math.PI / 180 * this.rotation) * this.distance * _loc_1;
			this.dragPosition = new Vector3D(_loc_2, _loc_3, _loc_4);
			this.dispatch();
			return;
		}// end function
		
	}
}
